{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.spatial import distance as dist\n",
    "from imutils import perspective\n",
    "from imutils import contours\n",
    "#import argparse\n",
    "import imutils\n",
    "import numpy as np\n",
    "import cv2\n",
    "\n",
    "def midpoint(A, B):\n",
    "    return ((A[0] + B[0]) * 0.5, (A[1] + B[1]) * 0.5)\n",
    "\n",
    "image = cv2.imread(\"example_04.png\")\n",
    "\n",
    "'''\n",
    "coin_img = cv2.imread(\"standard_object.png\")\n",
    "if not image.data:\n",
    "    print(\"read image wrong!\")\n",
    "if not coin_img.data:\n",
    "    print(\"read coin_img wrong\")\n",
    "'''\n",
    "# imageROI = np.ones((100, 88, 3))\n",
    "# imageROI =  coin_img[0:10, 0: 10]\n",
    "# image[0:10, 0:10] = imageROI\n",
    "\n",
    "# load the image, convert it to grayscale, and blur it slightly\n",
    "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n",
    "gray = cv2.GaussianBlur(gray, (7, 7), 0)\n",
    "\n",
    "# perform edge detection, then perform a dilation + erosion to\n",
    "# close gaps in between object edges\n",
    "\n",
    "edged = cv2.Canny(gray, 50, 100)\n",
    "edged = cv2.dilate(edged, None, iterations=1)\n",
    "edged = cv2.erode(edged, None, iterations=1)\n",
    "\n",
    "# find contours in the edge map\n",
    "cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
    "cnts = imutils.grab_contours(cnts)\n",
    "\n",
    "# sort the contours from left-to-right and initialize the\n",
    "# 'pixels per metric' calibration variable\n",
    "(cnts, _) = contours.sort_contours(cnts)\n",
    "pixelsPerMetric = None\n",
    "width = 3.5\n",
    "\n",
    "# loop over the contours individually\n",
    "\n",
    "for c in cnts:\n",
    "    # if the contour is not sufficiently large, ignore it\n",
    "    if cv2.contourArea(c) < 200:\n",
    "         continue\n",
    "\n",
    "    # compute the rotated bounding box of the contour\n",
    "    orig = image.copy()\n",
    "    box = cv2.minAreaRect(c)\n",
    "    box = cv2.boxPoints(box)\n",
    "    box = np.array(box, dtype=\"int\")\n",
    "\n",
    "    # order the points in the contour such that they appear\n",
    "    # in top-left, top-right, bottom-right, and bottom-left \n",
    "    # order, then draw the outline of the rotated bounding  \n",
    "    # box\n",
    "    \n",
    "    box = perspective.order_points(box)\n",
    "    cv2.drawContours(orig, [box.astype(\"int\")], -1, (0, 255, 0), 2)\n",
    "\n",
    "    # loop over the original points and draw them\n",
    "    for (x, y) in box:\n",
    "        cv2.circle(orig, (int(x), int(y)), 5, (0, 0, 255), -1)\n",
    "    # unpack the ordered bounding box, then compute the midpoint\n",
    "    # between the top-left and top-right coordinates, followed by\n",
    "    # the midpoint between bottom-left and bottom-right coordinates\n",
    "    \n",
    "    (tl, tr, br, bl) = box\n",
    "    (tltrX, tltrY) = midpoint(tl, tr)\n",
    "    (blbrX, blbrY) = midpoint(bl, br)\n",
    "    \n",
    "    # compute the midpoint between the top-left and top-right points,\n",
    "    # followed by the midpoint between the top-righ and bottom-right\n",
    "    \n",
    "    (tlblX, tlblY) = midpoint(tl, bl)\n",
    "    (trbrX, trbrY) = midpoint(tr, br)\n",
    "    \n",
    "    # draw the midpoints on the image\n",
    "    \n",
    "    cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)\n",
    "    cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)   \n",
    "    cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1) \n",
    "    cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)\n",
    "    \n",
    "    # draw lines between the midpoints\n",
    "    \n",
    "    cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)), (255, 0, 255), 2)\n",
    "    cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)), (255, 0, 255), 2)\n",
    "    # compute the Euclidean distance between the midpoints\n",
    "\n",
    "    dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))\n",
    "    dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))\n",
    "    \n",
    "    # if the pixels per metric has not been initialized, then\n",
    "    # compute it as the ratio of pixels to supplied metric\n",
    "    # (in this case, inches)\n",
    "    \n",
    "    if pixelsPerMetric is None:\n",
    "        pixelsPerMetric = dB / width\n",
    "    # compute the size of the object\n",
    "    dimA = dA / pixelsPerMetric\n",
    "    dimB = dB / pixelsPerMetric\n",
    "    \n",
    "    # draw the object sizes on the image\n",
    "    \n",
    "    cv2.putText(orig, \"{:.1f}in\".format(dimA),\n",
    "    (int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 2)\n",
    "    cv2.putText(orig, \"{:.1f}in\".format(dimB),\n",
    "    (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 2)\n",
    "    \n",
    "    # show the output image\n",
    "    cv2.imshow(\"Image\", orig)\n",
    "    cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
